﻿using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Newtonsoft.Json;
using Serilog;
using TSNPro.MyControl;
using TSNPro.Utils;

namespace TSNPro.Communication.Sender
{
    public class SerialPortParam
    {
        public int BaudRate { get; set; }

        public Parity Parity { get; set; }

        public StopBits StopBits { get; set; }

        public int DataBits { get; set; }
    }

    public class SerialPortSender : BaseSender
    {
        SerialPort _serialPort=new SerialPort();
        public SerialPortSender()
        {
            _serialPort.DataReceived += SerialPort_DataReceived;
        }

        public override bool Send(byte[] arr)
        {
            _serialPort.Write(arr,0, arr.Length);
            return true;
        }

        private async void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            await Task.Delay(10);
            int byteCount = _serialPort.BytesToRead;
            byte[] byteArray = new byte[byteCount];
            _serialPort.Read(byteArray, 0, byteCount);

            if (ValidCommand(byteArray))
            {
                DataReceivedWrap(byteArray);
            }
        }

        private bool ValidCommand(byte[] cmd)
        {
            if(cmd.Length != 8)
            {
                return false;
            }

            if (cmd[0]==0x5A)
            {
                byte[] crc = CrcUtils.Crc16ToBytes(cmd.Take(6).ToArray());

                return (crc[0] == cmd[6] && crc[1] == cmd[7]);    
            }
            else
            {
                return false;
            }
        }

        public override Control GetConfigWidget()
        {
            SerialPortControl control = new SerialPortControl();
            control.SetCommunication(this);
            return control;
        }

        public override bool ConnectToHost()
        {
            try
            {
                if (_serialPort.IsOpen)
                {
                    _serialPort.Close();
                }
                string address = _obj["Address"].ToString();
                //JsonConvert.DeserializeObject<SerialPortParam>()
                SerialPortParam sp = _other.ToObject<SerialPortParam>();
                _serialPort.PortName = address;
                _serialPort.BaudRate = sp.BaudRate;
                _serialPort.Parity = sp.Parity;
                _serialPort.StopBits = sp.StopBits;
                _serialPort.DataBits = sp.DataBits;

                _serialPort.Open();
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return false;
            }
        }

        public override bool IsConnected()
        {
            return _serialPort.IsOpen;
        }
    }
}
